package trackexplorer.wizard;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

import trackexplorer.Activator;
import trackexplorer.editors.MapViewer;

public class LayersPage extends WizardPage implements Listener{

    private List   layers;
    private List   layMaps;
    private List   maps;
    private Button bt;
    private Button bt1;
    private Button bt2;
    private Text   text;
    private Button btDown;
    private Button btUp;

    public LayersPage(){
        super("Page2");
        setTitle("Layers & Maps");
        setDescription("Create layers and add maps.");
    }

    public void createControl(final Composite parent){
        Preferences prefs = new ConfigurationScope().getNode(MapViewer.ID)
            .node("maps");
        Composite composite = new Composite(parent, SWT.NULL);
        GridLayout gl = new GridLayout();
        gl.numColumns = 5;
        composite.setLayout(gl);
        GridData data = new GridData(GridData.FILL_BOTH);
        data.verticalSpan = 6;
        data.widthHint = 150;
        GridData data1 = new GridData(GridData.FILL_VERTICAL);
        data1.verticalSpan = data.verticalSpan - 1;
        data1.horizontalSpan = 2;
        data1.widthHint = data.widthHint;

        new Label(composite, SWT.NONE).setText("Layers");
        new Label(composite, SWT.NONE);
        new Label(composite, SWT.NONE).setText("Maps on layer");
        new Label(composite, SWT.NONE);
        new Label(composite, SWT.NONE).setText("Maps");

        text = new Text(composite, SWT.BORDER);
        text.setLayoutData(new GridData(GridData.FILL));
        bt = new Button(composite, SWT.NONE);
        bt.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
        bt.setText("+");
        bt.setToolTipText("Add layer");
        bt.addListener(SWT.Selection, this);
        layMaps = new List(composite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
            | SWT.H_SCROLL);
        layMaps.setLayoutData(data);
        new Label(composite, SWT.NONE);
        maps = new List(composite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
            | SWT.H_SCROLL);
        maps.setLayoutData(data);
        layers = new List(composite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        layers.setLayoutData(data1);
        layers.addListener(SWT.Selection, this);
        try{
            TreeSet<String> set = new TreeSet<String>();
            set.addAll(Arrays.asList(prefs.keys()));
            maps.setItems(set.toArray(new String[0]));
        }catch(BackingStoreException e){
            e.printStackTrace();
        }
        btUp = new Button(composite, SWT.NONE);
        btUp.addListener(SWT.Selection, this);
        {
            Image image = Activator.getDefault().getImageRegistry()
                .getDescriptor(Activator.IMG_ARROW).createImage();
            ImageData imgD = Activator.rotate(image.getImageData(), SWT.LEFT);
            imgD.transparentPixel = imgD.getPixel(0, 0);
            btUp.setImage(new Image(parent.getDisplay(), imgD));
        }
        bt1 = new Button(composite, SWT.NONE);
        {
            Image image = Activator.getDefault().getImageRegistry()
                .getDescriptor(Activator.IMG_ARROW).createImage();
            ImageData imgD = Activator.rotate(image.getImageData(), SWT.DOWN);
            imgD.transparentPixel = imgD.getPixel(0, 0);
            bt1.setImage(new Image(parent.getDisplay(), imgD));
        }
        bt1.addListener(SWT.Selection, this);
        bt2 = new Button(composite, SWT.NONE);
        {
            Image image = Activator.getDefault().getImageRegistry()
                .getDescriptor(Activator.IMG_ARROW).createImage();
            ImageData imgD = image.getImageData();
            imgD.transparentPixel = imgD.getPixel(0, 0);
            bt2.setImage(new Image(parent.getDisplay(), imgD));
        }
        bt2.addListener(SWT.Selection, this);
        btDown = new Button(composite, SWT.NONE);
        btDown.addListener(SWT.Selection, this);
        {
            Image image = Activator.getDefault().getImageRegistry()
                .getDescriptor(Activator.IMG_ARROW).createImage();
            ImageData imgD = Activator.rotate(image.getImageData(), SWT.RIGHT);
            imgD.transparentPixel = imgD.getPixel(0, 0);
            btDown.setImage(new Image(parent.getDisplay(), imgD));
        }
        new Label(composite, SWT.NONE);
        Button button = new Button(composite, SWT.NONE);
        button.setText("Save");
        button.addSelectionListener(new SelectionListener(){

            public void widgetDefaultSelected(SelectionEvent e){}

            public void widgetSelected(SelectionEvent event){
                FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
                dialog.setFilterExtensions(new String[]{"*.xml", "*.*"});
                String open = dialog.open();
                if(open != null){
                    try{
                        AtlasExportWizard wiz = (AtlasExportWizard)getWizard();
                        wiz.save(new File(open));
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                }
            }
        });
        setControl(composite);
    }

    public void activate(){
        Event event = new Event();
        event.widget = bt;
        handleEvent(event);
    }

    @Override
    public IWizardPage getNextPage(){
        return null;
    }

    @Override
    public boolean canFlipToNextPage(){
        return false;
    }

    public void handleEvent(Event event){
        AtlasExportWizard wiz = (AtlasExportWizard)getWizard();
        if(event.widget == bt){
            String[] selection = layers.getSelection();
            String s = text.getText();
            if(!"".equals(s)){
                wiz.addLayer(s);
                text.setText("");
            }
            Set<String> lays = wiz.getLayers();
            String[] array = lays.toArray(new String[lays.size()]);
            layers.setItems(array);
            if(selection.length == 0 && array.length > 0){
                selection = new String[]{array[0]};
            }
            layers.setSelection(selection);
            Event ev = new Event();
            ev.widget = layers;
            handleEvent(ev);
            return;
        }
        String[] laySel = layers.getSelection();
        if(laySel == null || laySel.length == 0){
            return;
        }
        if(event.widget == btUp){
            String[] mapSel = layMaps.getSelection();
            if(mapSel == null || mapSel.length == 0){
                message("Select map first.");
                return;
            }
            LinkedList<String> maps = wiz.getMaps(laySel[0]);
            for(String m: mapSel){
                int idx = maps.indexOf(m);
                maps.add(Math.max(idx - 1, 0), maps.remove(idx));
            }
            String[] array = maps.toArray(new String[maps.size()]);
            layMaps.setItems(array);
            layMaps.setSelection(mapSel);
            return;
        }
        if(event.widget == btDown){
            String[] mapSel = layMaps.getSelection();
            if(mapSel == null || mapSel.length == 0){
                message("Select map first.");
                return;
            }
            LinkedList<String> maps = wiz.getMaps(laySel[0]);
            for(String m: mapSel){
                int idx = maps.indexOf(m);
                maps.add(Math.min(idx + 1, maps.size() - 1), maps.remove(idx));
            }
            String[] array = maps.toArray(new String[maps.size()]);
            layMaps.setItems(array);
            layMaps.setSelection(mapSel);
            return;
        }
        if(event.widget == bt1){
            String[] mapSel = maps.getSelection();
            if(mapSel == null || mapSel.length == 0){
                message("Select map first.");
                return;
            }
            for(String m: mapSel){
                wiz.addMap(laySel[0], m);
            }
            LinkedList<String> maps = wiz.getMaps(laySel[0]);
            String[] array = maps.toArray(new String[maps.size()]);
            layMaps.setItems(array);
            return;
        }
        if(event.widget == bt2){
            String[] mapSel = layMaps.getSelection();
            if(mapSel == null || mapSel.length == 0){
                message("Select map first.");
                return;
            }
            LinkedList<String> maps = wiz.getMaps(laySel[0]);
            for(String m: mapSel){
                maps.remove(m);
            }
            String[] array = maps.toArray(new String[maps.size()]);
            layMaps.setItems(array);
            return;
        }
        if(event.widget == layers){
            LinkedList<String> maps = wiz.getMaps(laySel[0]);
            String[] array = maps.toArray(new String[maps.size()]);
            layMaps.setItems(array);
            return;
        }
    }

    private void message(String str){
        MessageDialog.openInformation(PlatformUI.getWorkbench()
            .getActiveWorkbenchWindow().getShell(), "Export atlas", str);
    }
}
